Skip to content

docs(agents,skills,pm): make the remaining one-shot-executor fences executable, and re-lock the retirement pin - #16357

Draft
os-steve wants to merge 1 commit into
mainfrom
claude/issue-14768-executable-fences-and-relock
Draft

docs(agents,skills,pm): make the remaining one-shot-executor fences executable, and re-lock the retirement pin#16357
os-steve wants to merge 1 commit into
mainfrom
claude/issue-14768-executable-fences-and-relock

Conversation

@os-steve

@os-steve os-steve commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Fixes #14768
Fixes #15959
Fixes #15957
Fixes #15975

Deliverable 2 of the census card — the rewrites — for the three hits that sit
outside .claude/skills/pm-dispatch/SKILL.md (that fourth hit rides its own PR
on the same file), folded with the corpus programme's re-lock pass and the two
protocol clauses that land on the same governed files.

The criterion is not re-argued here. It is the landed bullet in
.claude/skills/pm-dispatch/references/dispatch-runbook.md: an instruction
addressed to a one-shot executor must be terminal within the run — either
allow-with-trace, or forbid. Each site below becomes one of those two forms, one
sentence per rule, and no sentence outside the hits moves.

What changed

The three rewrites

site form before after
.claude/agents/os-dev.md forbid PR state you did not set belongs to another actor — go ask, never correct never correct it; the question goes in the report, and blocked where it blocks the work
.claude/skills/pm-dispatch/references/dispatch-runbook.md allow-with-trace if the real producer is in another package, notify first and then fix on the producer side fix on the producer side directly; the landing point and the reasoning go in the report and the PR body
.claude/skills/checklist-test/SKILL.md + docs/qa/platform-checklist/RUNNER.md forbid the repro stays in the session and the runner stops there and waits for the maintainer the run ends there with that report, and the maintainer is not waited on

The runbook line is dispatch-word boilerplate the PM copies verbatim, so the
unexecutable form reached a one-shot dev unaltered. The checklist-test clause
declares itself the same rule as RUNNER rule 2, so both copies move in one
stroke — RUNNER already calls that report a completed verdict, which is exactly
what makes the wait removable rather than merely shortened.

Two clauses on .claude/agents/os-dev.md

  • The line-ratchet block gains the ruled exception: where the dispatch names
    measurement-first for a governed ledger at zero headroom, land the lines,
    leave the ceiling row untouched, let the ratchet read red and report the
    measured count. blocked stays the default for every other unpayable ratchet,
    and raising a ceiling yourself stays forbidden in both branches.
  • The PR rules gain the clause-2 carrier line: a claim that declares the
    contract-review clause hangs needs:contract-review on the PR in the same
    write that opens it, and reports the pair predicate's exit code. A
    single-carrier hang converts a legitimate future clear into an unprovable one,
    and the defect is committed at hang time.

The re-lock pass

scripts/pm/check-skill-line-ratchet.mjs — one pin row, the retirement
playbook's max-table-row-bytes, 328 to 326. That is the value the gate itself
has been printing as an advisory on every run; lowering a shrink-only pin is
always legitimate and needs no ruling. No other row moves. After the change the
gate prints no advisory at all — every ceiling and every pin sits at its
landed count.

Line accounting — the currency is deleted content, never re-wrap

os-dev.md is 403/403 with zero headroom, and this PR adds two rules to it. The
2026-08-17 ruling is that re-wrap may not be used to buy lines; the legal
currency is deleting content. So both lines are paid for by deletions, and the
deletions are named:

  • the ratchet block loses two rationale clauses — that the ratchet governs
    content volume with lines as its machine-readable proxy, and that the gate
    cannot tell the two net-0 shapes apart. Both are why text; the operative
    discriminator (does the fold buy lines for new content) and the operative rules
    around it are kept verbatim.
  • the PR-body block loses the sentence explaining that squash concatenates every
    commit message. The rule it justifies — card relations are declared once in
    the body, never as a per-commit trailer — is unchanged and complete alone.

Landed counts, from the gate's own verdict lines at the head below:

.claude/agents/os-dev.md is 403 lines (ceiling 403; headroom 0).
.claude/skills/pm-dispatch/references/dispatch-runbook.md is 241 lines (ceiling 241; headroom 0).
.claude/skills/checklist-test/SKILL.md is 234 lines (ceiling 238; headroom 4).
.claude/skills/spec-property-retirement/SKILL.md: widest table row is 326 bytes (pin 326; headroom 0).

checklist-test/SKILL.md came in at 234 lines before and after — the bullet
re-wraps inside itself around the changed sentence and buys nothing. Both other
ratcheted files are line-neutral.

One reading correction worth recording: scripts/check-skills-token-ratchet.mjs
does not cover .claude/skills/** at all — its population is the published
skills/ catalog. The ratchet that governs checklist-test/SKILL.md is the line
ratchet above. The token ratchet was run anyway, self-test and live, both green.

Verification

Every exit code captured before any pipe (redirect, then read $?), and each
verdict quoted from the gate's own line rather than from a bare status.

  • Derived family, at the final head f5c08e9589:
    node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack
    over the five-path change set — 39 families. All 39 run, all green.
    Reconciled: --ran reports 39 derived, 39 run, 0 NOT-MEASURED, 0 UNRUN.
  • pnpm check:pm-skill-ratchet (self-test then live) green, and the live run
    prints zero advisory lines.
  • node scripts/check-skills-token-ratchet.mjs --self-test and the live run:
    both green.
  • pnpm check:pm-skill-id-lint, pnpm check:skill-frame-sync,
    pnpm check:pm-governed-prose, pnpm check:agent-model-declared,
    pnpm check:nul-bytes, pnpm check:platform-checklist,
    pnpm check:ratchet-remedy-authority, pnpm check:pm-dispatch-gates: green.
  • node scripts/pm/check-half-states.mjs --self-test: green. Every rewritten and
    every deleted sentence was grepped across scripts/, .github/, packages/
    and docs/ — no pin names any of them, in either the old or the new spelling.
  • node scripts/pm/check-governed-merges.mjs --test over the five paths:
    exit 3, GOVERNED, naming exactly one regime — .claude/**, three paths.
    No second regime, which is why this is one PR.
  • Every .claude/hooks/*.selftest.sh: five files, all green.
  • Whole-repo pnpm lint (eslint . --no-inline-config) through
    scripts/pm/os-verify-lock.sh, slot issue-14768: VERDICT command-exit 0.
    Whole-repo, not narrowed.

Everything above was re-run at f5c08e9589 after the merge of main, not only
at the pre-merge commit.

Governed endgame

The diff hits .claude/**, so this stays a draft PR: no seat flips it ready,
enqueues it, arms auto-merge, or approves it. skip-changeset applies — nothing
in the diff publishes from any released package.

维护者速读(草稿)

改了什么 —— 三处写给一次性执行者、却要求它「先问 / 先报备 / 停下等人」的指令,改成
它真能做完的形态:要么直接做并把判断写进报告,要么明确禁止并把问题留在报告里。另外在
dev 定义里补两条规则(零余量受管账本的测量优先例外、clause-2 双载体在开 PR 同笔挂上),
并把技能行数棘轮里一条 2 字节的 pin 收紧到实测值。

为什么改 —— 一次性 dev / runner 没有中途提问的通道。一条要求它「问完再继续」的围栏,
实际上把「做还是不做还是自己拿主意」整个三选一交回给了它,而作者以为自己已经把这个选择
拦下了。这是一类事故,不是措辞偏好;判据本身早已落地,这里只是把存量文本改到判据上。

风险与代价(含回滚) —— 纯指令文本 + 一个棘轮 pin,不动任何运行时代码,门禁全绿。
风险面在于「安全漏洞复现要不要等人」那一条:改后运行以报告终局,复现仍然留在会话里、
不上 GitHub,RUNNER 原文本来就把这份报告称作完整判定,所以禁令强度未降。回滚是单次
git revert,无数据迁移、无下游依赖。

席位意见 ——

你要做的 —— 读一下三处改写后的句子是否仍然是你要的强度(尤其是安全复现那条),然后
人工合并。⛔ 不要由任何 AI 席位合并、入队或批准;.claude/** 是受管面。

Generated by Claude Code


Generated by Claude Code


Generated by Claude Code

…xecutable, and re-lock the retirement pin

Every instruction addressed to a one-shot executor must be terminal within the
run. Four sites still asked for a mid-run channel that executor does not have;
three of them are rewritten here (the fourth rides its own PR on SKILL.md):

- os-dev.md — "go ask" about PR state a dev did not set becomes forbid plus a
  terminal route: never correct it, put the question in the report, and report
  `blocked` where it blocks the work.
- dispatch-runbook.md — the verbatim dispatch-word sentence about a producer in
  another package drops its "notify first, then fix" sequencing and keeps the
  trace: fix at the producer, record the landing point and the reasoning.
- checklist-test/SKILL.md and its RUNNER.md twin — an auth/authz repro no longer
  says "stop and wait for the maintainer"; the run ends with that report, which
  the RUNNER rule already calls a completed verdict. Both copies move together.

Two clauses on the same file, both line-neutral and paid for by deleted
rationale, never by re-wrap: the line-ratchet clause gains the ruled
measurement-first exception for a governed ledger at zero headroom, and the PR
rules gain the clause-2 carrier line (the dev hangs `needs:contract-review` on
the PR in the same write and reports the pair predicate's exit).

The skill line ratchet's `max-table-row-bytes` pin for the retirement playbook
drops 328 to 326, the value the gate has been printing as an advisory on every
run. Lowering a shrink-only pin needs no ruling; the gate now prints none.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 6, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Sep 6, 2026
@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

ACCEPT — contract-tier review of PR #16357, head f5c08e9589 (skills seat, 2026-09-06T15:4xZ).

Implemented-by: claude/issue-14768-executable-fences-and-relock (os-dev subagent, opus under the measured quota exemption recorded on #14768 at 14:05Z)
Reviewed-by: session_019RfFHiRCSs3JXLK4cwcfox (skills seat)

Verified in a detached compare worktree at the PR head, not from the report:

  • Five files, +19/−18, one governed regime (.claude/** ×3; docs/qa/platform-checklist/RUNNER.md and the ratchet map are not on the register — one PR, as the dev read it). The three census hits outside SKILL.md are executable now: os-dev.md's 「去问」 is a forbid plus a terminal route (⛔ 永不去纠正;疑问进报告,挡住报 blocked); dispatch-runbook.md's producer-side line drops 「报备后」 (直接按生产者侧修,落点与理由写进报告和 PR 正文); checklist-test/SKILL.md's 「停下等维护者」 and its RUNNER.md rule-2 twin move in lockstep to the run ending with that report — the seat read both: the reproduction still stays in the session and off GitHub, the report is still the complete verdict, so the disclosure guardrail's strength is unchanged. Two clauses land on os-dev.md at 403/403: the measurement-first exception for a zero-headroom governed ledger (os-dev.md: the line-ratchet clause says "report blocked" where the dispatch protocol's measurement-first route is the ruled exception for a zero-headroom governed ledger — narrow the clause #15959) and the clause-② carrier line (a Clause-②: yes claim ⇒ needs:contract-review hung on the PR in the same write, --pair N exit in the report — [finding] a single-carrier needs:contract-review hang makes the eventual clear indistinguishable from a strip — the defect is committed at hang time and only surfaces at landing #15975's os-dev.md half). Paid by NAMED rationale deletions the seat checked one by one — the squash-concatenation why-sentence and the two why-clauses of the ratchet block (「棘轮治理的是内容体量,行数只是机读代理」, 「门禁分不出两种 net-0」) — with every rule of that block still present in the two folded lines; no re-wrap bought a line. The re-lock pass lowers the retirement playbook's row pin 328 → 326 ([finding] the skill line ratchet has been printing an unclaimed 2-byte pin tighten for spec-property-retirement/SKILL.md on every run #15957); the ratchet prints zero advisories.
  • Gates at the head: check-skill-line-ratchet exit 0 (os-dev.md 403/403 · dispatch-runbook.md 241/241 · checklist-test/SKILL.md 234/238 · retirement pin 326/326, 0 advisories); check-governed-merges --test on the five paths exit 3; check-half-states --self-test 2535; check-skill-id-lint, check-skill-frame-sync exit 0; all five .claude/hooks/*.selftest.sh exit 0; every deleted or rewritten sentence greps to 0 over scripts/, .claude/hooks, .github (no pin names them); every added line 90–117 bytes. The dev's report adds the derived union 39/39 with --ran at 0 NOT-MEASURED (byte-identical derivation before and after its main merge), the token ratchet green, and whole-repo pnpm lint through the verify lock (exit 0, 111 s, unnarrowed). PR checks on f5c08e9589: 23 success, 11 skipped, 0 failed (34 runs, converged).
  • Report hygiene: os-dev-report on all four cards, JSON closes; skip-changeset read back; one MCP call declared; no model identifier. One seat edit to the PR body, recorded here: the fourth relation line read Refs #15975; this PR carries that card's LAST half (its SKILL.md half rides PR docs(pm-dispatch): six protocol-line repairs, line-neutral on both governed text surfaces #16339 as Refs), so the seat changed it to Fixes #15975 through REST (read back). The dev's mechanism correction is accepted: check-skills-token-ratchet.mjs reads only the published skills/ catalog, never .claude/skills/** — the next briefs say so.

Ruling on the open question — A. SKILL.md's PM-side ratchet summary row does not carry the new measurement-first exception; the exception fires only when the dispatch itself names measurement-first, so the PM is by construction the party who knows it. No line is bought on a zero-headroom file to restate a rule the PM authors; if the next SKILL.md flight (#16352 / #16229, after PR #16339 and PR #16271 land) finds a fold that pays for it, it rides there as a rider — recorded on those cards' dispatch, not owed.

Landing regime: governed (.claude/**) ⇒ the PR stays a draft; reviewers os-zhuang + hotlong requested in this same act, needs-user-decision added, the final 维护者速读 posted as the next comment; human merge. On the merge #14768 · #15959 · #15957 · #15975 close by Fixes. The two flights this PR unblocks (the PR #15955 patch round on the ratchet map, and #16262 + #16351's os-dev.md half) launch now against this head with git merge-tree proofs, the shape PR #16003 used.


Generated by Claude Code

@claude
claude Bot requested review from hotlong and os-zhuang September 6, 2026 15:40
@claude

claude Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

维护者速读

改了什么:三处写给一次性执行者、却要求它「先问 / 先报备 / 停下等人」的指令,改成它真能做完的形态——要么直接做并把判断写进报告,要么明确禁止并把问题留在报告里;另外在 dev 定义里补两条规则(零余量受管账本的测量优先例外;Clause-②: yes 认领在开 PR 同笔挂复审标签并报对账退出码),并把技能行数棘轮里一条 pin 收紧到实测值(328 → 326)。五个文件,行数全部不变或在顶下。

为什么改:一次性 dev / runner 没有中途提问的通道。一条要求它「问完再继续」的围栏,实际上把「做、不做、还是自己拿主意」整个交回给了它,而作者以为已经把这个选择拦下了。判据早已落地(dev 契约里的「一次性执行者」原则),这里只是把存量文本改到判据上。

要请您看一眼的:安全漏洞复现那一条(checklist-test 与 RUNNER 规则 2 两处同文)。改后运行以那份报告终局,复现仍留在会话里、不上 GitHub;RUNNER 原文本来就把这份报告称作完整判定,所以禁令强度未降,只是删掉了「等维护者」这个执行者做不到的动作。请确认这是您要的强度。

代价与回滚:纯指令文本加一个棘轮 pin,不动运行时代码,门禁全绿;席位逐句核过被删的三句都是「为什么」而不是规则本身。回滚是一次 git revert

席位意见:建议合并。受管面(.claude/**),人工合并;合并后 #14768 · #15959 · #15957 · #15975 四张卡关闭(#15975 的另一半在 PR #16339 里,已合到 SKILL.md 那边)。


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment